﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ZephyrisNet_PC;

namespace TestConsole
{
    class Program
    {
        static Thread THRD_SEND;
        static Thread THRD_RECEIVE;

        static bool isError = false;

        static NetworkMainClass networkManager = new NetworkMainClass();
        static Helpers helpers = new Helpers();

        static long sessionID = 0;

        static int simNum = 0;
        static List<AImodule> aiModuleList = new List<AImodule>();
        static System.Threading.TimerCallback netUpdateCallback;
        static System.Threading.Timer aiTimer;

        static void Main(string[] args)
        {
            Console.WriteLine("Enter the number of simulated players:- ");
            string sim = Console.ReadLine();

            if (!Int32.TryParse(sim, out simNum))
            {
                Console.WriteLine("Invalid number, setting simulated players to 0");
            }
            else
            {
                Console.WriteLine("Number of simulated players is set to {0}", simNum);
            }

            Console.WriteLine(System.Environment.NewLine);

            isError = !networkManager.StartNetwork(
                Constants.NetworkMode.LAN_Online, 
                System.Net.IPAddress.Parse("195.3.138.253"), 
                22222
                );

            if (!isError)
            {
                sessionID = helpers.GetUnixEpochTime().Ticks;

                THRD_RECEIVE = new Thread(StartServer);
                THRD_SEND = new Thread(StartClient);

                THRD_RECEIVE.Start();
                Thread.Sleep(50);
                THRD_SEND.Start();

                Thread.Sleep(50);
                THRD_SEND = new Thread(StartClient);
                THRD_SEND.Start();

                netUpdateCallback = new System.Threading.TimerCallback(AIThread);

                Console.WriteLine("Network Supernode initialized.");

                Console.WriteLine("Create virtual player nodes...");

                for (int i = 0; i < simNum; i++)
                {
                    aiModuleList.Add(new AImodule(networkManager));
                    Console.WriteLine("Created player at <{0}, {1}, {2}>", aiModuleList[i].player.pos.X, aiModuleList[i].player.pos.Y, aiModuleList[i].player.pos.Z); 
                }

                Console.WriteLine("Created {0} virtual player nodes!", simNum);

                aiTimer = new Timer(netUpdateCallback, null, 0, 33);
            }
            else
            {
                Console.WriteLine("Network Supernode not initialized!");
            }
        }


        static void StartServer()
        {
            DataPacket dataPacket = new DataPacket();

            bool hasNewData = false;

            networkManager.ReceiveP2P();

            while (!hasNewData)
            {
                dataPacket = networkManager.GetDataPacket();

                if (dataPacket.Data != "")
                {
                    switch (dataPacket.Data.Substring(0, 4))
                    {
                        case "INIT":
                            Console.WriteLine("Broadcasting game session. " + sessionID.ToString());
                            networkManager.SendP2P("SEID:" + sessionID.ToString());
                            //networkManager.SendP2P("INIT:" + sessionID.ToString());
                            break;

                        case "CONN":
                            Console.WriteLine("Authorizing player.");
                            networkManager.Send("CONN:" + sessionID.ToString());
                            break;

                        case "POSN":
                            Console.WriteLine(dataPacket.Data.Substring(5));
                            break;

                        default:
                            Console.WriteLine("Data received from " + dataPacket.Endpoint.ToString()
                        + " on " + dataPacket.Timestamp.ToString()
                        + " - " + dataPacket.Data);
                            break;
                    }

                    //hasNewData = true;
                }
            }

            Console.WriteLine("Done!");
        }

        static void StartClient()
        {
            bool response = networkManager.SendP2P("This is some test data");

            if (response)
            {
                Console.WriteLine("Done!");
            }
            else
            {
                Console.WriteLine("Error!");
            }
            
        }

        static void AIThread(Object callback)
        {
            foreach (AImodule ai in aiModuleList)
            {
                ai.NetworkUpdate();
            }
        }
    }
}
